package nxu.it.dao.Impl;

import nxu.it.dao.TodoStorage;
import nxu.it.model.Todo;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class MemoryTodoStorage implements TodoStorage {
    private static List<Todo> todoList = new ArrayList<>();
    private static ConcurrentHashMap<Integer, Todo>[] todoMap = new ConcurrentHashMap[0];
    @Override
    public List<Todo> list(){
        return todoList;
    }

    @Override
    public Optional<Todo> get(int id){
        for (Todo value : todoList) {
            if (value.getId() == id) {
                return Optional.of(value);
            }
        }
        for (ConcurrentHashMap<Integer, Todo>map : todoMap) {
            Todo todo = map.get(id);
            if(todo != null){
                return Optional.of(todo);
            }
        }
        return null;
    }

    @Override
    public Boolean save(Todo todo){
        if(todo != null && todo.getId() != null && todo.getContent() != null && !todo.getContent().isBlank()){
            todoList.add(todo);
            ConcurrentHashMap<Integer, Todo> map = new ConcurrentHashMap<>();
            map.put(todo.getId(), todo);
            todoMap = Arrays.copyOf(todoMap, todoMap.length + 1);
            todoMap[todoMap.length - 1] = map;
        }
        return true;
    }

    @Override
    public Boolean update(Todo todo){
        if(todo == null || todo.getId() == null){
            return false;
        }
        Optional<Todo> todoOpt = get(todo.getId());
        todoOpt.ifPresent(t -> {
            t.setComplete(todo.getComplete());
            t.setContent(todo.getContent());
        });
        for(ConcurrentHashMap<Integer, Todo> map : todoMap){
            if(map.containsKey(todo.getId())){
                map.put(todo.getId(), todo);
                break;
            }
        }
        return true;
    }

    @Override
    public Boolean delete(int id){
        todoList.removeIf(todo -> todo.getId() == id);
        for(int i = 0;i < todoMap.length;i++){
            if(todoMap[i].containsKey(id)){
                todoMap[i].remove(id);
                break;
            }
        }
        return true;
    }

    @Override
    public void check(int id){
        Optional<Todo> todoOpt = get(id);
        todoOpt.ifPresent(t -> t.setComplete(!t.getComplete()));
    }

}
